package cn.suzhang.jsharp.common.config.shiro;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.suzhang.jsharp.module.sys.entity.SysResource;
import cn.suzhang.jsharp.module.sys.entity.SysRole;
import cn.suzhang.jsharp.module.sys.entity.SysUser;
import cn.suzhang.jsharp.module.sys.service.UserService;

/**
 * 认证和授权类
 * 
 * @author suzhang
 * @since 2018-02-11
 *
 */
@Component
public class MyRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();

		SysUser dbUser = userService.findByUserName(sysUser.getUserName());
		Set<String> roleSet = new HashSet<String>();
		Set<String> shiroPermissions = new HashSet<>();
		Set<SysRole> roles = dbUser.getRoles();
		for (SysRole role : roles) {
			Set<SysResource> resources = role.getResources();
			for (SysResource resource : resources) {
				shiroPermissions.add(resource.getSourceKey());
			}
			roleSet.add(role.getRoleKey());
		}

		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setRoles(roleSet);
		authorizationInfo.setStringPermissions(shiroPermissions);
		return authorizationInfo;

	}

	/**
	 * 认证
	 * 
	 * @author suzhang
	 * @since 2018-02-11
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();

		SysUser dbUser = userService.findByUserName(username);

		// 账号不存在
		if (dbUser == null) {
			throw new UnknownAccountException("账号或密码不正确");
		}

		Object credentials = token.getCredentials();
		if (credentials == null) {
			throw new UnknownAccountException("账号或密码不正确");
		}
		String password = new String((char[]) credentials);

		// 密码错误
		if (!password.equals(dbUser.getUserPwd())) {
			throw new IncorrectCredentialsException("账号或密码不正确");
		}

		return new SimpleAuthenticationInfo(dbUser, password, getName());

	}
}
